#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <cstring>

#define PORT 8080

void handle_client(int new_socket) {
    char buffer[1024] = {0};
    
    // 接收客户端数据（阻塞调用）
    int valread = read(new_socket, buffer, 1024);
    if (valread < 0) {
        perror("read failed");
        close(new_socket);
        return;
    }
    std::cout << "Received from client: " << buffer << std::endl;

    // 回复客户端数据
    const char *response = "Hello from server!";
    send(new_socket, response, strlen(response), 0);
    std::cout << "Response sent to client." << std::endl;

    // 关闭客户端连接
    close(new_socket);
}

int main() {
    int server_fd, new_socket;
    struct sockaddr_in address;
    int addrlen = sizeof(address);

    // 创建TCP套接字
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    // 绑定套接字到端口
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    // 开始监听连接请求
    if (listen(server_fd, 3) < 0) {
        perror("listen failed");
        exit(EXIT_FAILURE);
    }

    std::cout << "TCP Server waiting for client connections..." << std::endl;

    while (true) {
        // 接受客户端连接（阻塞调用）
        if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
            perror("accept failed");
            continue;
        }

        std::cout << "Connected to client!" << std::endl;

        // 创建子进程来处理客户端请求
        pid_t pid = fork();
        if (pid == 0) {
            // 子进程处理客户端请求
            close(server_fd);  // 子进程不再需要监听套接字
            handle_client(new_socket);
            exit(0);  // 子进程完成后退出
        } else if (pid < 0) {
            perror("fork failed");
        }

        // 父进程继续监听连接
        close(new_socket);
    }

    return 0;
}
